﻿using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Async;

namespace MvcPipe
{
    public abstract class PipeletController : AsyncController
    {
        private readonly PipeletActionInvoker pipeletActionInvoker = new PipeletActionInvoker();

        protected void ExecutePipelets(IDictionary<string,PipeletDescription> pipelets,ActionResult bootstrapperResult = null )
        {
            Contract.Requires<ArgumentNullException>(pipelets != null, "pipelets");

            // Copy the names over:
            foreach( var kv in pipelets )
            {
                kv.Value.Name = kv.Key;
            }

            // Render the overall layout/boostrapper
            bootstrapperResult = bootstrapperResult ?? View(pipelets.Values);
            bootstrapperResult.ExecuteResult(ControllerContext);
            HttpContext.Response.Flush();

            // Spin of the async operation of rendering all the pipelets( real asynchronicity depends on the pipelets themselves, if all are synchronous this will be
            // synchronous as well )
            AsyncManager.OutstandingOperations.Increment();

            pipeletActionInvoker.InvokePipeletsAsync(HttpContext, pipelets.Values).ContinueWith(task =>
            {
                HttpContext.Response.Flush();
                AsyncManager.OutstandingOperations.Decrement();

                if (task.Exception != null)
                {
                    HttpContext.AddError(task.Exception);
                }
            });
        }
    }
}